﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Interactivity;
using System.Windows.Controls;
using System.Windows.Threading;
using System.Collections.Specialized;
using System.Windows.Media.Animation;
    
namespace TouchControls
{
    public abstract class ListItemAnimateBehaviorBase : Behavior<ListBox>
    {
        public Duration Duration { get; set; }
        public TimeSpan Delay { get; set; }
        public TimeSpan InitialDelay { get; set; }

        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.Loaded += new System.Windows.RoutedEventHandler(AssociatedObject_Loaded);
        }

        protected override void OnDetaching()
        {
            AssociatedObject.Loaded -= new System.Windows.RoutedEventHandler(AssociatedObject_Loaded);
            base.OnDetaching();
        }

        void AssociatedObject_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            Storyboard sb = new Storyboard();
            var ressourceName = "Stb" + sb.GetHashCode();

            IEnumerable<ListBoxItem> items = this.GetItems(sb);

            TimeSpan delay = InitialDelay;
            foreach (var item in items)
            {
                //item.Opacity = 0;            
                
                AnimateItem(sb, item, delay);
                delay = delay + Delay;
            }
            AssociatedObject.Resources.Add(ressourceName, sb);
            sb.Completed += (senderStb, arg) =>
                {
                    AssociatedObject.Resources.Remove(ressourceName);
                };
            sb.Begin();
        }

        protected DoubleAnimation AddAnimation(Storyboard sb, TimeSpan delay)
        {
            var animation = new DoubleAnimation();
            animation.BeginTime = delay;
            //animation.FillBehavior = FillBehavior.Stop;            
            animation.Duration = this.Duration;
            sb.Children.Add(animation);
            return animation;
        }

        protected abstract void AnimateItem(Storyboard sb, ListBoxItem item, TimeSpan delay);

        private IEnumerable<ListBoxItem> GetItems(Storyboard sb)
        {
            IEnumerable<ListBoxItem> items;
            if (AssociatedObject.ItemsSource == null)
            {
                items = AssociatedObject.Items.Cast<ListBoxItem>();
            }
            else
            {
                var itemsSource = AssociatedObject.ItemsSource;
                if (itemsSource is INotifyCollectionChanged)
                {
                    var collection = itemsSource as INotifyCollectionChanged;
                    collection.CollectionChanged += (s, cce) =>
                        {
                            if (cce.Action == NotifyCollectionChangedAction.Add)
                            {
                                var itemContainer =
                                    AssociatedObject.ItemContainerGenerator.ContainerFromItem(cce.NewItems[0]) as ListBoxItem;

                                AnimateItem(sb, itemContainer, TimeSpan.FromMilliseconds(0));
                            }
                        };
                }
                ListBoxItem[] itemsSub = new ListBoxItem[AssociatedObject.Items.Count];
                for (int i = 0; i < itemsSub.Length; i++)
                {
                    itemsSub[i] = AssociatedObject.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem;
                }
                items = itemsSub;
            }
            return items;
        }
    }
}
